package com.echo.aichat.user;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;

import com.echo.aichat.user.dto.UserLoginInput;
import com.echo.aichat.user.dto.UserRegisterInput;
import com.echo.context.AiUserIdContext;
import com.echo.vo.AiUserVo;
import io.qifan.infrastructure.common.exception.BusinessException;
import lombok.AllArgsConstructor;
import org.babyfish.jimmer.client.FetchBy;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;


@RequestMapping("user")
@RestController
@AllArgsConstructor
public class UserController {
    private final UserRepository userRepository;
    /**
     * 用户是否登录是通过 StpUtil.getLoginIdAsString() 判断的。
     * 如果未登录，会抛出 NotLoginException。
     在用户已登录的情况下，会进一步使用登录 ID 查询数据库，获取用户信息。
     Sa-Token 提供了强大的登录状态管理机制，配合全局异常处理，可以确保未登录用户无法访问受保护的资源。*/
   @GetMapping
    public @FetchBy(value = "FETCHER", ownerType = UserRepository.class) User userInfo() {
       // 得到用户id
       String userId = StpUtil.getLoginIdAsString();
       AiUserIdContext.setAiUserIdContext(userId);
       System.out.println("aichat"+userId);
        return userRepository.findById(StpUtil.getLoginIdAsString(), UserRepository.FETCHER)
            .orElseThrow(() -> new BusinessException("用户信息不存在"));
    }

    @PostMapping("login")
    public SaTokenInfo login(@RequestBody UserLoginInput input) {
        System.out.println();
        User databaseUser = userRepository.findByPhone(input.getPhone())
                .or(() -> userRepository.findByEmail(input.getEmail())) // 尝试查找手机号后再查邮箱
                .orElseThrow(() -> new BusinessException("用户名/密码错误"));
        if (!BCrypt.checkpw(input.getPassword(), databaseUser.password())) {
            throw new BusinessException("用户名/密码错误");
        }
// 得到用户id
        String userId = databaseUser.id();
        AiUserIdContext.setAiUserIdContext(userId);
        System.out.println("aichat"+userId);
        StpUtil.login(databaseUser.id());
        return StpUtil.getTokenInfo();
    }

    @PostMapping("register")
    public SaTokenInfo register(@RequestBody UserRegisterInput input) {
        Optional<User> byPhone = userRepository.findByPhone(input.getPhone());
        if (byPhone.isPresent()) {
            return null;
        }
        User save = userRepository.save(UserDraft.$.produce(draft -> {
            draft.setPhone(input.getPhone())
                    .setEmail(input.getEmail())
                .setPassword(BCrypt.hashpw(input.getPassword()));
        }));
        StpUtil.login(save.id());
        return StpUtil.getTokenInfo();
    }
}
